package service

import (
	"context"
	"log"
	"time"

	"servermerge/internal/callback"
	"servermerge/internal/client"
	"servermerge/internal/model"
	"servermerge/internal/store"
)

func buildDSNs(dbs []model.DBConn) []string {
	result := make([]string, len(dbs))
	for i, db := range dbs {
		result[i] = db.ToDSN()
	}
	return result
}

// 启动合服流程
func StartMerge(req model.MergeStartRequest) (*model.CallbackToMiddle, error) {
	id := "merge_" + time.Now().Format("20060102_150405")
	task := &model.MergeTask{
		ID:        id,
		Request:   req,
		Status:    model.StatusRunning,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}
	store.SaveTask(task)

	// 对中台异步，后台执行同步调用
	go func(id string, req model.MergeStartRequest) {
		log.Printf("[MERGE][%s] 开始同步调用游戏服", id)
		gameReq := model.GameExecuteRequest{
			SourceDSNs: buildDSNs(req.OldDBs),
			TargetDSN:  req.NewDB.ToDSN(),
			Options:    req.Options,
			TraceID:    id,
		}
		resp, err := client.CallGameServer(context.Background(), gameReq)
		if err != nil {
			log.Printf("[MERGE][%s] 游戏服请求失败: %v", id, err)
			store.UpdateTask(id, func(t *model.MergeTask) {
				t.Status = model.StatusFailed
				t.Result = &model.GameExecuteResponse{Status: "failed", Detail: err.Error()}
			})
			callback.NotifyMiddle(context.Background(), req.CallbackURL, model.CallbackToMiddle{
				MergeID: id, Status: "failed", Detail: err.Error(),
			})
			return
		}

		log.Printf("[MERGE][%s] 游戏服返回: %s", id, resp.Status)
		status := model.StatusSuccess
		if resp.Status != "success" {
			status = model.StatusFailed
		}

		store.UpdateTask(id, func(t *model.MergeTask) {
			t.Status = status
			t.Result = resp
		})

		callback.NotifyMiddle(context.Background(), req.CallbackURL, model.CallbackToMiddle{
			MergeID: id,
			Status:  resp.Status,
			Detail:  resp.Detail,
			Stats:   resp.Stats,
		})
	}(id, req)

	return &model.CallbackToMiddle{MergeID: id, Status: "RUNNING"}, nil
}

// 查询任务
func GetTaskStatus(id string) *model.MergeTask {
	return store.GetTask(id)
}
